// Message Handler - Message buffers to manage the transfering of messages from one method to another.
// Message Data - Object that holds message information.
// Copyright (C) 2009  Robert N. Tenney
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
using System;
using System.Drawing;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace RTenney.Utility
{
    /// <summary>
    /// MessageHandler is a static class that allows for the passing of information from called
    /// classes and methods to the main program with ease. It comes with 4 predefined message buffers.
    /// One for general messages, debug messages, status messages and timekeeper duration logs.
    /// </summary>
    public static class MessagesHandler
    {
        private static List<MessageData> messages = new List<MessageData>();
        private static List<MessageData> debugMessages = new List<MessageData>();
        private static List<MessageData> statusMessages = new List<MessageData>();
        private static List<MessageData> timeKeeperData = new List<MessageData>();
        
        /// <summary>
        /// Retrieves a specified message buffer. The returned list is a generic List with
        /// the messages packed in a MessageData object.
        /// </summary>
        /// <param name="type">Type of buffer to retrieve.</param>
        /// <returns>A generic List of MessageData messages.</returns>
        public static List<MessageData> GetMessageList(MessageType type){
            switch (type) {
                case MessageType.DEBUG:
                    return debugMessages;
                case MessageType.MESSAGES:
                    return messages;
                case MessageType.STATUS:
                    return statusMessages;
                case MessageType.TIMEKEEPERDATA:
                    return timeKeeperData;
            }
            return null;
        }
        
        /// <summary>
        /// Adds a message to the specifies message buffer.
        /// </summary>
        /// <param name="type">Type of message buffer to add to.</param>
        /// <param name="message">MessageData object containing the message information.</param>
        public static void Add(MessageType type, MessageData message){
            switch (type) {
                case MessageType.DEBUG:
                    debugMessages.Add(message);
                    break;
                case MessageType.MESSAGES:
                    messages.Add(message);
                    break;
                case MessageType.STATUS:
                    statusMessages.Add(message);
                    break;
                case MessageType.TIMEKEEPERDATA:
                    timeKeeperData.Add(message);
                    break;
            }
        }
        
        /// <summary>
        /// Adds a message to the specified message buffer. 
        /// </summary>
        /// <param name="type">Type of buffer to add message to.</param>
        /// <param name="message">The message to add.</param>
        /// <param name="color">The color to flag the message with.</param>
        public static void Add(MessageType type, string message, Color color){
            MessageData temp = new MessageData();
            temp.Message = message;
            temp.MessageColor = color;
            Add(type, temp);
        }
        
        /// <summary>
        /// Adds a message to the specified message buffer.
        /// </summary>
        /// <param name="type">Type of buffer to add the message to.</param>
        /// <param name="message">The message to add.</param>
        public static void Add(MessageType type, string message){
            Add(type, message, Color.Black);
        }
    }
    
    /// <summary>
    /// A structure to hold some data to store with the message in the buffers.
    /// </summary>
    public struct MessageData{
        private string message;
        private Color color;
        
        /// <summary>
        /// Gets or sets the message.
        /// </summary>
        public String Message{
            get{
                return this.message;
            } set{
                this.message = value;
            }
        }
        
        /// <summary>
        /// Gets or sets the color to flag this message with.
        /// </summary>
        public Color MessageColor{
            get{
                return this.color;
            }set{
                this.color = value;
            }
        }
        
        /// <summary>
        /// Compares this object to another to determine if they are equal.
        /// </summary>
        /// <param name="obj">Object to compare to.</param>
        /// <returns>True if the object is the same, false otherwise.</returns>
        public override bool Equals(object obj)
        {
            if (obj is MessageData) {
                return ((MessageData)obj).Message == this.Message && ((MessageData)obj).MessageColor == this.MessageColor;
            }
            return false;
        }
        
        /// <summary>
        /// Generates a unique hashcode for this object.
        /// </summary>
        /// <returns>The hashcode as an integer.</returns>
        public override int GetHashCode()
        {
            int hcm = this.Message.GetHashCode();
            int hcc = this.MessageColor.GetHashCode();
            
            return hcm ^ hcc;
        }
        
        /// <summary>
        /// Compares two MessageData objects to determine if they are the same.
        /// </summary>
        /// <param name="dat1">The first object.</param>
        /// <param name="dat2">The second object.</param>
        /// <returns>True if they are the same, false otherwise.</returns>
        public static bool operator ==(MessageData dat1, MessageData dat2){
            return dat1.Equals(dat2);
        }
        
        /// <summary>
        /// Compares if two MessageData objects are not the same.
        /// </summary>
        /// <param name="dat1">The first object.</param>
        /// <param name="dat2">The second object.</param>
        /// <returns>True if they are not the same, false otherwise.</returns>
        public static bool operator !=(MessageData dat1, MessageData dat2){
            return !dat1.Equals(dat2);
        }
    }
    
    /// <summary>
    /// The available message types to store in the buffers.
    /// </summary>
    public enum MessageType{
        /// <summary>
        /// A buffer for general messages.
        /// </summary>
        MESSAGES,
        /// <summary>
        /// A buffer for debugging messages.
        /// </summary>
        DEBUG,
        /// <summary>
        /// A buffer for status messages.
        /// </summary>
        STATUS,
        /// <summary>
        /// A buffer for the Timekeeper to use for duration results.
        /// </summary>
        TIMEKEEPERDATA
    }
}
